package com.simafei.flow.web.controller;


import com.simafei.flow.core.ExecutionResult;
import com.simafei.flow.core.api.Api;
import com.simafei.flow.core.api.impl.ApiExecutor;
import com.simafei.flow.web.common.CommonResult;
import com.simafei.flow.web.domain.req.ApiExecReq;
import com.simafei.flow.web.domain.req.ApiReq;
import com.simafei.flow.web.domain.req.PageParam;
import com.simafei.flow.web.domain.req.VariableReq;
import com.simafei.flow.web.domain.resp.ApiResp;
import com.simafei.flow.web.domain.resp.PageResult;
import com.simafei.flow.web.service.IApiService;
import com.simafei.flow.web.util.VariableUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;


/**
 * 算法模型表 http api 入口
 *
 * @author generator
 * @since 2023-05-05
 */
@Tag(name = "API管理")
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ApiController {

    private final ApiExecutor apiExecutor;

    private final IApiService apiService;

    @Operation(summary = "根据Id查询API")
    @GetMapping("/get")
    public CommonResult<ApiResp> get(@RequestParam Long id) {
        return CommonResult.success(apiService.get(id));
    }

    @Operation(summary = "新增API")
    @PostMapping("/add")
    public CommonResult<Long> add(@Validated @RequestBody ApiReq req) {
        VariableUtils.checkDuplicateVarNames(req.getReqVariables());
        return CommonResult.success(apiService.add(req));
    }

    @Operation(summary = "修改API")
    @PostMapping("/update")
    public CommonResult<Void> update(@RequestParam Long id, @Validated @RequestBody ApiReq req) {
        VariableUtils.checkDuplicateVarNames(req.getReqVariables());
        boolean ret = apiService.update(id, req);
        return ret ? CommonResult.success() : CommonResult.error();
    }

    @Operation(summary = "设置API响应变量")
    @PostMapping("/setRespVariables")
    public CommonResult<Void> setRespVariables(@RequestParam Long id, @Validated @RequestBody List<VariableReq> req) {
        boolean ret = apiService.setRespVariables(id, req);
        return ret ? CommonResult.success() : CommonResult.error();
    }

    @Operation(summary = "根据Id删除API")
    @PostMapping("/delete")
    public CommonResult<Void> delete(@RequestParam Long id) {
        boolean ret = apiService.removeById(id);
        return ret ? CommonResult.success() : CommonResult.error();
    }

    @Operation(summary = "分页查询所有API列表")
    @PostMapping("/page")
    public CommonResult<PageResult<ApiResp>> page(@Validated @RequestBody PageParam param) {
        return CommonResult.success(apiService.queryPage(param));
    }

    @Operation(summary = "分页查询可用的API列表")
    @PostMapping("/enabled/page")
    public CommonResult<PageResult<ApiResp>> availablePage(@Validated @RequestBody PageParam param) {
        return CommonResult.success(apiService.queryPage(param, true));
    }

    @Operation(summary = "根据名称查询API列表")
    @PostMapping("/query")
    public CommonResult<List<ApiResp>> query(@RequestParam String apiName) {
        return CommonResult.success(apiService.queryByName(apiName));
    }

    @Operation(summary = "测试API执行获取结果", description = "执行API获取结果")
    @PostMapping("/execute")
    public CommonResult<List<Map<String, Object>>> execute(@Validated @RequestBody ApiExecReq req) {
        try {
            ApiResp apiResp = apiService.get(req.getApiId());
            ExecutionResult execute = apiExecutor.execute(Api.builder()
                            .template(apiResp.getTemplate())
                            .httpUrl(apiResp.getHttpUrl())
                            .serializeType(apiResp.getSerializeType())
                            .httpMethod(apiResp.getHttpMethod())
                            .serializeScript(apiResp.getSerializeScript())
                            .build(), req.getParam());
            return CommonResult.success(execute.getResults());
        } catch (Throwable e) {
            return CommonResult.error(String.format("API执行失败[%s]", e.getMessage()));
        }
    }


    @Operation(summary = "获取解析模板")
    @GetMapping("/template")
    public CommonResult<String> getTemplate(@RequestParam String name) {
        return CommonResult.success(apiExecutor.template(name));
    }

}
